#include <iostream>
#include <string>
#include <cstring>
#include <cerrno>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>

void Usage(std::strign proc)
{
    std::cout<<"Usage: "<<proc<<"proc"<<std::endl;
}

void ServiceIO(int new_sock)
{
    while(true)
        {
            char buffer[1024];
            memste(buffer,0,sizeof(buffer));
            ssize_t s=read(new_sock,buffer,sizeof(buffer)-1);
            if(s>0)
            {
                buffer[s]=0;
                std::cout<<"client# "<<buffer<<std::endl;

                std::string echo_string=">>>server<<<";
                echo_string+=buffer;

                write(new_sock,echo_string.c_str(),echo_string.size());
            }
            else if(s==0)
            {
                std::cout<<"client quit ..."<<std::endl;
                break;
            }
            else
            {
                std::cerr<<"read error "<<std::endl;
                break;
            }
        }
}

int main(int argc,char*argv[])
{
    if(argc!=2)
    {
        Usage(argv[0]);
        return 1;
    }


    //1.创建套接字
    int listen_sock=socket(AF_INET,SOCK_STREAM,0);
    if(listen_sock<0)
    {
        std::cerr<<"socket error : "<<errno<<std::endl;
        return 2;
    }

    //2.bind
    struct sockaddr_in local;
    memset(&local,0,sizeof(local));
    local.sin_family=AF_INET;
    local.sin_port=htons(atoi(argv[1]));
    local.sin_addr.s_addr=INADDR_ANY;

    if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0)
    {
        std::cerr<<"bind error"<<errno<<std::endl;
        return 3;
    }
    //3.tcp面向连接，即通信时需要建立连接
    //一定有人主动建立
    //server是被人连接的
    //设置套接字是listen状态，本质是允许用户连接
    //3.监听
    const int back_log=5;
    if(listen(listen_sock,back_log)<0)
    {
        std::cerr<<"listen error "<<std::endl;
        return 4;
    }

    signal(SIGCHLD,SIG_IGN);

    for(;;)
    {
        struct sockaddr_in peer;
        socklen_t len=sizeof(peer);
        int new_sock = accept(listen_sock,(struct sockaddr*)&peer,&len);
        if(new_sock<0)
        {
            continue;
        }

        std::cout<<"get a new link ..."<<std::endl;

        pid_t id=fork();
        if(id<0)
        {
            continue;
        }
        else if(if==0)
        {//child
            ServiceIO(new_sock);
            exit(0);
        }
        else
        {//father

        }

        
    }

    return 0;
}